पायथनच्या http.server (पूर्वीचे BaseHTTPServer) ला कस्टमाइझ करून सोपे APIs, डायनॅमिक वेब सर्व्हर आणि शक्तिशाली इंटर्नल टूल्स बनवण्यासाठी एक सर्वसमावेशक मार्गदर्शक.
पायथनच्या बिल्ट-इन HTTP सर्वरमध्ये प्राविण्य: कस्टमायझेशनचा सखोल अभ्यास
पायथन त्याच्या "batteries-included" तत्त्वज्ञानासाठी प्रसिद्ध आहे, जे एक समृद्ध स्टँडर्ड लायब्ररी प्रदान करते. यामुळे डेव्हलपर्सना कमीत कमी बाह्य अवलंबनांसह कार्यक्षम ॲप्लिकेशन्स तयार करण्याचे सामर्थ्य मिळते. यापैकी एक सर्वात उपयुक्त, परंतु अनेकदा दुर्लक्षित राहिलेली बॅटरी म्हणजे बिल्ट-इन HTTP सर्व्हर. तुम्ही त्याला आधुनिक पायथन 3 नावाने http.server
म्हणून ओळखत असाल किंवा त्याच्या जुन्या पायथन 2 नावाने BaseHTTPServer
म्हणून, हे मॉड्यूल वेब प्रोटोकॉल्स समजून घेण्यासाठी आणि हलके-फुलके वेब सर्व्हिसेस तयार करण्यासाठी एक प्रवेशद्वार आहे.
जरी अनेक डेव्हलपर्सना याचा पहिला अनुभव डिरेक्टरीमधील फाइल्स सर्व्ह करण्यासाठी एका ओळीच्या कमांडच्या रूपात येतो, तरी त्याची खरी ताकद त्याच्या विस्तारक्षमतेमध्ये आहे. याच्या मूळ घटकांना सबक्लास करून, तुम्ही या साध्या फाइल सर्व्हरला एका सानुकूलित वेब ॲप्लिकेशनमध्ये, फ्रंटएंड डेव्हलपमेंटसाठी मॉक API मध्ये, IoT डिव्हाइसेससाठी डेटा रिसीव्हरमध्ये किंवा एका शक्तिशाली इंटर्नल टूलमध्ये बदलू शकता. हे मार्गदर्शक तुम्हाला मूलभूत गोष्टींपासून प्रगत कस्टमायझेशनपर्यंत घेऊन जाईल, जे तुम्हाला तुमच्या स्वतःच्या प्रोजेक्ट्ससाठी या विलक्षण मॉड्यूलचा लाभ घेण्यासाठी सुसज्ज करेल.
मूलभूत गोष्टी: कमांड लाइनवरून एक साधा सर्व्हर
कोडमध्ये जाण्यापूर्वी, चला सर्वात सामान्य वापराच्या केसकडे पाहूया. जर तुमच्याकडे पायथन इंस्टॉल केलेले असेल, तर तुमच्याकडे आधीपासूनच एक वेब सर्व्हर आहे. तुमच्या कॉम्प्युटरवरील कोणत्याही डिरेक्टरीमध्ये टर्मिनल किंवा कमांड प्रॉम्प्ट वापरून नेव्हिगेट करा आणि खालील कमांड चालवा (पायथन 3 साठी):
python -m http.server 8000
त्वरित, तुमच्याकडे पोर्ट 8000 वर एक वेब सर्व्हर चालू होईल, जो तुमच्या सध्याच्या लोकेशनमधील फाइल्स आणि सबडिरेक्टरीज सर्व्ह करेल. तुम्ही तुमच्या ब्राउझरवरून http://localhost:8000
येथे ॲक्सेस करू शकता. हे खालील गोष्टींसाठी अविश्वसनीयपणे उपयुक्त आहे:
- स्थानिक नेटवर्कवर फाइल्स त्वरीत शेअर करण्यासाठी.
- साध्या HTML, CSS, आणि JavaScript प्रोजेक्ट्सना क्लिष्ट सेटअपशिवाय तपासण्यासाठी.
- वेब सर्व्हर विविध रिक्वेस्ट्सना कसे हाताळतो हे तपासण्यासाठी.
तथापि, ही एक-ओळीची कमांड फक्त हिमनगाचे टोक आहे. हे एक पूर्व-निर्मित, सामान्य सर्व्हर चालवते. कस्टम लॉजिक जोडण्यासाठी, विविध रिक्वेस्ट प्रकार हाताळण्यासाठी, किंवा डायनॅमिक सामग्री तयार करण्यासाठी, आपल्याला आपली स्वतःची पायथन स्क्रिप्ट लिहावी लागेल.
मुख्य घटक समजून घेणे
या मॉड्यूलने तयार केलेल्या वेब सर्व्हरमध्ये दोन मुख्य भाग असतात: सर्व्हर आणि हँडलर. प्रभावी कस्टमायझेशनसाठी त्यांची वेगळी भूमिका समजून घेणे महत्त्वाचे आहे.
१. सर्व्हर: HTTPServer
सर्व्हरचे काम एका विशिष्ट पत्त्यावर आणि पोर्टवर येणाऱ्या नेटवर्क कनेक्शन्ससाठी ऐकणे आहे. हे ते इंजिन आहे जे TCP कनेक्शन्स स्वीकारते आणि त्यांना प्रक्रिया करण्यासाठी हँडलरकडे पाठवते. http.server
मॉड्यूलमध्ये, हे सामान्यतः HTTPServer
क्लासद्वारे हाताळले जाते. तुम्ही सर्व्हरचा पत्ता (एक टपल जसे की ('localhost', 8000)
) आणि एक हँडलर क्लास देऊन त्याचे एक इन्स्टन्स तयार करता.
याची मुख्य जबाबदारी नेटवर्क सॉकेटचे व्यवस्थापन करणे आणि रिक्वेस्ट-रिस्पॉन्स सायकलचे संयोजन करणे आहे. बहुतेक कस्टमायझेशनसाठी, तुम्हाला HTTPServer
क्लासमध्ये बदल करण्याची आवश्यकता भासणार नाही, परंतु हे जाणून घेणे आवश्यक आहे की ते तिथेच आहे आणि सर्व काही चालवत आहे.
२. हँडलर: BaseHTTPRequestHandler
इथेच खरी जादू घडते. हँडलर येणाऱ्या HTTP रिक्वेस्टला पार्स करण्यासाठी, क्लायंट काय मागत आहे हे समजून घेण्यासाठी, आणि योग्य HTTP रिस्पॉन्स तयार करण्यासाठी जबाबदार असतो. प्रत्येक वेळी जेव्हा सर्व्हरला नवीन रिक्वेस्ट मिळते, तेव्हा तो त्यावर प्रक्रिया करण्यासाठी तुमच्या हँडलर क्लासचा एक इन्स्टन्स तयार करतो.
http.server
मॉड्यूल काही पूर्व-निर्मित हँडलर्स प्रदान करते:
BaseHTTPRequestHandler
: हा सर्वात मूलभूत हँडलर आहे. तो रिक्वेस्ट आणि हेडर्स पार्स करतो परंतु GET किंवा POST सारख्या विशिष्ट रिक्वेस्ट मेथड्सना प्रतिसाद कसा द्यावा हे त्याला माहीत नसते. जेव्हा तुम्हाला सुरवातीपासून सर्वकाही तयार करायचे असेल तेव्हा इनहेरिट करण्यासाठी हा एक परिपूर्ण बेस क्लास आहे.SimpleHTTPRequestHandler
: हाBaseHTTPRequestHandler
पासून इनहेरिट करतो आणि सध्याच्या डिरेक्टरीमधून फाइल्स सर्व्ह करण्यासाठी लॉजिक जोडतो. जेव्हा तुम्हीpython -m http.server
चालवता, तेव्हा तुम्ही हा हँडलर वापरत असता. जर तुम्हाला डीफॉल्ट फाइल-सर्व्हिंग वर्तनावर कस्टम लॉजिक जोडायचे असेल तर हा एक उत्कृष्ट प्रारंभ बिंदू आहे.CGIHTTPRequestHandler
: हाSimpleHTTPRequestHandler
चा विस्तार करतो आणि CGI स्क्रिप्ट्सना देखील हाताळतो. आधुनिक वेब डेव्हलपमेंटमध्ये हे कमी सामान्य आहे परंतु लायब्ररीच्या इतिहासाचा एक भाग आहे.
जवळजवळ सर्व कस्टम सर्व्हर कार्यांसाठी, तुमचे काम BaseHTTPRequestHandler
किंवा SimpleHTTPRequestHandler
पासून इनहेरिट करणारा एक नवीन क्लास तयार करणे आणि त्याच्या मेथड्सना ओव्हरराइड करणे असेल.
तुमचा पहिला कस्टम सर्व्हर: एक "Hello, World!" उदाहरण
चला कमांड लाइनच्या पलीकडे जाऊन एका साध्या पायथन स्क्रिप्ट लिहूया, जी एका कस्टम मेसेजसह प्रतिसाद देईल. आम्ही BaseHTTPRequestHandler
पासून इनहेरिट करू आणि do_GET
मेथड लागू करू, जी कोणत्याही HTTP GET रिक्वेस्टला हाताळण्यासाठी आपोआप कॉल केली जाते.
custom_server.py
नावाची फाइल तयार करा:
# Use http.server for Python 3
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
hostName = "localhost"
serverPort = 8080
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
# 1. Send the response status code
self.send_response(200)
# 2. Send headers
self.send_header("Content-type", "text/html")
self.end_headers()
# 3. Write the response body
self.wfile.write(bytes("<html><head><title>My Custom Server</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is a custom server, created with Python's http.server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
print(f"Server started http://{hostName}:{serverPort}")
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
हे चालवण्यासाठी, तुमच्या टर्मिनलमध्ये python custom_server.py
चालवा. जेव्हा तुम्ही तुमच्या ब्राउझरमध्ये http://localhost:8080
ला भेट द्याल, तेव्हा तुम्हाला तुमचा कस्टम HTML संदेश दिसेल. तुम्ही वेगळ्या पाथला भेट दिल्यास, जसे की http://localhost:8080/some/path
, संदेश तो पाथ दर्शवेल.
चला do_GET
मेथडचे विश्लेषण करूया:
self.send_response(200)
: हे HTTP स्टेटस लाइन पाठवते.200 OK
यशस्वी रिक्वेस्टसाठी मानक प्रतिसाद आहे.self.send_header("Content-type", "text/html")
: हे एक HTTP हेडर पाठवते. येथे, आम्ही ब्राउझरला सांगतो की आम्ही पाठवत असलेली सामग्री HTML आहे. ब्राउझरने पेज योग्यरित्या रेंडर करण्यासाठी हे महत्त्वाचे आहे.self.end_headers()
: हे एक रिकामी ओळ पाठवते, जी HTTP हेडर्सच्या समाप्तीचा आणि रिस्पॉन्स बॉडीच्या सुरुवातीचा संकेत देते.self.wfile.write(...)
:self.wfile
एक फाइलसारखे ऑब्जेक्ट आहे ज्यात तुम्ही तुमची रिस्पॉन्स बॉडी लिहू शकता. याला स्ट्रिंग नव्हे, तर बाइट्सची अपेक्षा असते, म्हणून आपल्याला आपली HTML स्ट्रिंगbytes("...", "utf-8")
वापरून बाइट्समध्ये एन्कोड करावी लागेल.
प्रगत कस्टमायझेशन: व्यावहारिक कृती
आता तुम्हाला मूलभूत गोष्टी समजल्या आहेत, चला अधिक शक्तिशाली कस्टमायझेशन शोधूया.
POST रिक्वेस्ट हाताळणे (do_POST
)
वेब ॲप्लिकेशन्सना अनेकदा डेटा प्राप्त करण्याची आवश्यकता असते, उदाहरणार्थ, HTML फॉर्ममधून किंवा API कॉलवरून. हे सामान्यतः POST रिक्वेस्टने केले जाते. हे हाताळण्यासाठी, तुम्ही do_POST
मेथड ओव्हरराइड करता.
do_POST
च्या आत, तुम्हाला रिक्वेस्ट बॉडी वाचावी लागेल. या बॉडीची लांबी Content-Length
हेडरमध्ये नमूद केलेली असते.
येथे एका हँडलरचे उदाहरण आहे जो POST रिक्वेस्टमधून JSON डेटा वाचतो आणि तो परत पाठवतो:
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
class APIServer(BaseHTTPRequestHandler):
def _send_cors_headers(self):
"""Sends headers to allow cross-origin requests"""
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
self.send_header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type")
def do_OPTIONS(self):
"""Handles pre-flight CORS requests"""
self.send_response(200)
self._send_cors_headers()
self.end_headers()
def do_POST(self):
# 1. Read the content-length header
content_length = int(self.headers['Content-Length'])
# 2. Read the request body
post_data = self.rfile.read(content_length)
# For demonstration, let's log the received data
print(f"Received POST data: {post_data.decode('utf-8')}")
# 3. Process the data (here, we just echo it back as JSON)
try:
received_json = json.loads(post_data)
response_data = {"status": "success", "received_data": received_json}
except json.JSONDecodeError:
self.send_response(400) # Bad Request
self.end_headers()
self.wfile.write(bytes('{"error": "Invalid JSON"}', "utf-8"))
return
# 4. Send a response
self.send_response(200)
self._send_cors_headers()
self.send_header("Content-type", "application/json")
self.end_headers()
self.wfile.write(json.dumps(response_data).encode("utf-8"))
# Main execution block remains the same...
if __name__ == "__main__":
# ... (use the same HTTPServer setup as before, but with APIServer as the handler)
server_address = ('localhost', 8080)
httpd = HTTPServer(server_address, APIServer)
print('Starting server on port 8080...')
httpd.serve_forever()
CORS वर टीप: do_OPTIONS
मेथड आणि _send_cors_headers
फंक्शन क्रॉस-ओरिजिन रिसोर्स शेअरिंग (CORS) हाताळण्यासाठी समाविष्ट केले आहेत. जर तुम्ही तुमच्या API ला वेगळ्या ओरिजिन (डोमेन/पोर्ट) वरून सर्व्ह केलेल्या वेब पेजवरून कॉल करत असाल तर हे अनेकदा आवश्यक असते.
JSON प्रतिसादांसह एक साधा API तयार करणे
चला मागील उदाहरणाचा विस्तार करून बेसिक राउटिंगसह एक सर्व्हर तयार करूया. क्लायंट कोणती रिसोर्स रिक्वेस्ट करत आहे हे ठरवण्यासाठी आपण self.path
ॲट्रिब्यूट तपासू शकतो आणि त्यानुसार प्रतिसाद देऊ शकतो. हे आपल्याला एकाच सर्व्हरमध्ये अनेक API एंडपॉइंट्स तयार करण्याची परवानगी देते.
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs
# Mock data
users = {
1: {"name": "Alice", "country": "Canada"},
2: {"name": "Bob", "country": "Australia"}
}
class APIHandler(BaseHTTPRequestHandler):
def _set_headers(self, status_code=200):
self.send_response(status_code)
self.send_header("Content-type", "application/json")
self.send_header("Access-Control-Allow-Origin", "*")
self.end_headers()
def do_GET(self):
parsed_path = urlparse(self.path)
path = parsed_path.path
if path == "/api/users":
self._set_headers()
self.wfile.write(json.dumps(list(users.values())).encode("utf-8"))
elif path.startswith("/api/users/"):
try:
user_id = int(path.split('/')[-1])
user = users.get(user_id)
if user:
self._set_headers()
self.wfile.write(json.dumps(user).encode("utf-8"))
else:
self._set_headers(404)
self.wfile.write(json.dumps({"error": "User not found"}).encode("utf-8"))
except ValueError:
self._set_headers(400)
self.wfile.write(json.dumps({"error": "Invalid user ID"}).encode("utf-8"))
else:
self._set_headers(404)
self.wfile.write(json.dumps({"error": "Not Found"}).encode("utf-8"))
# Main execution block as before, using APIHandler
# ...
या हँडलरसह, तुमच्या सर्व्हरमध्ये आता एक प्राथमिक राउटिंग सिस्टीम आहे:
/api/users
ला केलेली GET रिक्वेस्ट सर्व युजर्सची यादी परत करेल./api/users/1
ला केलेली GET रिक्वेस्ट ॲलिसची माहिती परत करेल.- इतर कोणताही पाथ 404 Not Found त्रुटी देईल.
फाइल्स आणि डायनॅमिक सामग्री एकत्र सर्व्ह करणे
जर तुम्हाला डायनॅमिक API हवा असेल आणि त्याच सर्व्हरवरून स्टॅटिक फाइल्स (जसे की index.html
) देखील सर्व्ह करायच्या असतील तर काय? सर्वात सोपा मार्ग म्हणजे SimpleHTTPRequestHandler
पासून इनहेरिट करणे आणि जेव्हा एखादी रिक्वेस्ट तुमच्या कस्टम पाथशी जुळत नाही तेव्हा त्याच्या डीफॉल्ट वर्तनाकडे सोपवणे.
super()
फंक्शन येथे तुमचा सर्वात चांगला मित्र आहे. हे तुम्हाला पॅरेंट क्लासची मेथड कॉल करण्याची परवानगी देते.
import json
from http.server import SimpleHTTPRequestHandler, HTTPServer
class HybridHandler(SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/api/status':
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
response = {'status': 'ok', 'message': 'Server is running'}
self.wfile.write(json.dumps(response).encode('utf-8'))
else:
# For any other path, fall back to the default file-serving behavior
super().do_GET()
# Main execution block as before, using HybridHandler
# ...
आता, जर तुम्ही त्याच डिरेक्टरीमध्ये index.html
फाइल तयार केली आणि ही स्क्रिप्ट चालवली, तर http://localhost:8080/
ला भेट दिल्यास तुमची HTML फाइल सर्व्ह होईल, तर http://localhost:8080/api/status
ला भेट दिल्यास तुमचा कस्टम JSON प्रतिसाद मिळेल.
पायथन 2 वर एक टीप (BaseHTTPServer
)
जरी पायथन 2 आता समर्थित नसले तरी, तुम्हाला जुना कोड सापडू शकतो जो HTTP सर्व्हरच्या त्या आवृत्तीचा वापर करतो. संकल्पना समान आहेत, परंतु मॉड्यूलची नावे भिन्न आहेत. येथे एक द्रुत अनुवाद मार्गदर्शक आहे:
- पायथन 3:
http.server
-> पायथन 2:BaseHTTPServer
,SimpleHTTPServer
- पायथन 3:
socketserver
-> पायथन 2:SocketServer
- पायथन 3:
from http.server import BaseHTTPRequestHandler
-> पायथन 2:from BaseHTTPServer import BaseHTTPRequestHandler
मेथडची नावे (do_GET
, do_POST
) आणि मूळ लॉजिक समान राहतात, ज्यामुळे जुन्या स्क्रिप्ट्सना पायथन 3 मध्ये पोर्ट करणे तुलनेने सोपे होते.
प्रोडक्शनसाठी विचार: पुढे कधी जायचे
पायथनचा बिल्ट-इन HTTP सर्व्हर एक विलक्षण साधन आहे, परंतु त्याच्या काही मर्यादा आहेत. तो योग्य पर्याय केव्हा आहे आणि तुम्हाला अधिक मजबूत समाधानाकडे कधी वळले पाहिजे हे समजून घेणे महत्त्वाचे आहे.
१. कनकरन्सी आणि परफॉर्मन्स
डीफॉल्टनुसार, HTTPServer
सिंगल-थ्रेडेड आहे आणि रिक्वेस्ट्स क्रमाने प्रक्रिया करतो. जर एका रिक्वेस्टला प्रक्रिया करण्यासाठी जास्त वेळ लागला, तर तो इतर सर्व येणाऱ्या रिक्वेस्ट्सना ब्लॉक करेल. थोड्या अधिक प्रगत वापरासाठी, तुम्ही मल्टी-थ्रेडेड सर्व्हर तयार करण्यासाठी socketserver.ThreadingMixIn
वापरू शकता:
from socketserver import ThreadingMixIn
from http.server import HTTPServer
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
pass
# In your main block, use this instead of HTTPServer:
# webServer = ThreadingHTTPServer((hostName, serverPort), MyServer)
हे कनकरन्सीमध्ये मदत करत असले तरी, ते उच्च-कार्यक्षमता, उच्च-ट्रॅफिक असलेल्या प्रोडक्शन वातावरणासाठी डिझाइन केलेले नाही. पूर्ण-विकसित वेब फ्रेमवर्क आणि ॲप्लिकेशन सर्व्हर (जसे की Gunicorn किंवा Uvicorn) कार्यक्षमता, संसाधन व्यवस्थापन आणि स्केलेबिलिटीसाठी ऑप्टिमाइझ केलेले आहेत.
२. सुरक्षा
http.server
सुरक्षेला प्राथमिक लक्ष म्हणून तयार केलेले नाही. त्यात क्रॉस-साइट स्क्रिप्टिंग (XSS), क्रॉस-साइट रिक्वेस्ट फोर्जरी (CSRF), किंवा SQL इंजेक्शनसारख्या सामान्य वेब असुरक्षिततेविरूद्ध अंगभूत संरक्षण नाही. Django, Flask आणि FastAPI सारखे प्रोडक्शन-ग्रेड फ्रेमवर्क हे संरक्षण आउट-ऑफ-द-बॉक्स प्रदान करतात.
३. वैशिष्ट्ये आणि ॲबस्ट्रॅक्शन
तुमचे ॲप्लिकेशन जसजसे वाढेल, तसतसे तुम्हाला डेटाबेस इंटिग्रेशन (ORMs), टेम्पलेट इंजिन, अत्याधुनिक राउटिंग, युजर ऑथेंटिकेशन आणि मिडलवेअर यांसारखी वैशिष्ट्ये हवी असतील. तुम्ही हे सर्व http.server
वर स्वतः तयार करू शकता, परंतु तुम्ही मुळात एक वेब फ्रेमवर्क पुन्हा तयार करत असाल. Flask, Django आणि FastAPI सारखे फ्रेमवर्क हे घटक सु-संरचित, चाचणी केलेले आणि देखरेख करण्यायोग्य पद्धतीने प्रदान करतात.
http.server
यासाठी वापरा:
- HTTP शिकण्यासाठी आणि समजून घेण्यासाठी.
- जलद प्रोटोटाइपिंग आणि प्रूफ-ऑफ-कॉन्सेप्ट्ससाठी.
- साधे, फक्त अंतर्गत वापरासाठी टूल्स किंवा डॅशबोर्ड तयार करण्यासाठी.
- फ्रंटएंड डेव्हलपमेंटसाठी मॉक API सर्व्हर तयार करण्यासाठी.
- IoT किंवा स्क्रिप्ट्ससाठी हलके-फुलके डेटा कलेक्शन एंडपॉइंट्ससाठी.
फ्रेमवर्ककडे यासाठी वळा:
- सार्वजनिक वेब ॲप्लिकेशन्ससाठी.
- ऑथेंटिकेशन आणि डेटाबेस इंटरॅक्शनसह जटिल APIs साठी.
- ज्या ॲप्लिकेशन्समध्ये सुरक्षा, कार्यक्षमता आणि स्केलेबिलिटी महत्त्वपूर्ण आहे त्यांच्यासाठी.
निष्कर्ष: साधेपणा आणि नियंत्रणाची शक्ती
पायथनचा http.server
हा भाषेच्या व्यावहारिक रचनेचा पुरावा आहे. हे वेब प्रोटोकॉलसह काम करणाऱ्या प्रत्येकासाठी एक साधा तरीही शक्तिशाली पाया प्रदान करते. त्याच्या रिक्वेस्ट हँडलर्सना कस्टमाइझ करायला शिकून, तुम्ही रिक्वेस्ट-रिस्पॉन्स सायकलवर सूक्ष्म नियंत्रण मिळवता, ज्यामुळे तुम्ही पूर्ण वेब फ्रेमवर्कच्या ओझ्याशिवाय अनेक उपयुक्त साधने तयार करू शकता.
पुढच्या वेळी जेव्हा तुम्हाला जलद वेब सर्व्हिस, मॉक API, किंवा फक्त HTTP सह प्रयोग करण्याची आवश्यकता असेल, तेव्हा या बहुमुखी मॉड्यूलची आठवण ठेवा. हे फक्त फाइल सर्व्हरपेक्षा अधिक आहे; हे तुमच्या वेब-आधारित निर्मितीसाठी एक कोरा कॅनव्हास आहे, जो थेट पायथन स्टँडर्ड लायब्ररीमध्ये समाविष्ट आहे.